package com.zhangshitong.springbootModel.log.aop;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.zhangshitong.springbootModel.base.DTO;
import com.zhangshitong.springbootModel.base.ResMessage;
import com.zhangshitong.springbootModel.log.annotation.Log;
import com.zhangshitong.springbootModel.log.annotation.LogMethod;
import com.zhangshitong.springbootModel.log.entity.BusinessLog;
import com.zhangshitong.springbootModel.mapper.LogMapper;
import com.zhangshitong.springbootModel.utils.ClientContext;
import com.zhangshitong.springbootModel.utils.ClientContextHolder;
import com.zhangshitong.springbootModel.utils.JsonUtil;

/**
 * 操作日誌切面
 * @author Administrator
 *
 */
@Component
@Aspect
public class LogAspect {

	@Autowired
	LogMapper logMapper;
	
	
	@Pointcut("execution(* com.zhangshitong.springbootModel.*.controller.*.*(..))")
	private void aspectJMethod(){};
	
	
	@Around("aspectJMethod()") 
	public Object doAround(JoinPoint joinPoint){
		ResMessage o = null;
		
		ClientContext context = ClientContextHolder.getInstance().getClientContext();
		
		Object target = joinPoint.getTarget();
		Log log = target.getClass().getAnnotation(Log.class);
		
		MethodSignature ms = (MethodSignature) joinPoint.getSignature();
		LogMethod lm = ms.getMethod().getAnnotation(LogMethod.class);
		
		
		StringBuffer original_data = new StringBuffer("");
		
		Object[] args = joinPoint.getArgs();
		//请求数据源
		Object reqData = null;
		for(Object arg : args){
			if(arg.getClass().equals(DTO.class)){
				reqData = arg;
				break;
			}
		}
		original_data.append("request:\n");
		if(null != reqData){
			try {
				original_data.append(JsonUtil.toJson(reqData));
			} catch (Exception e) {
				
				e.printStackTrace();
			}
		}
		try {
			o = (ResMessage) ((ProceedingJoinPoint) joinPoint).proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		
		HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
		//System.out.println(request.getRequestURI());
		if(null != log  && null != lm && null != request && null != context){
			BusinessLog blog = new BusinessLog();
			blog.setHandler(context.getUserName());
			blog.setHandler_ip(context.getRequestIP());
			blog.setLog_type("02");
			blog.setOper_time(new Date());
			blog.setUser_name(context.getToken());
			
			String methodName = ms.getName().toLowerCase();
			
			if(methodName.startsWith("add") || methodName.startsWith("save") || methodName.startsWith("submit")){
				blog.setOper_type("01");
			}else if(methodName.startsWith("edit") || methodName.startsWith("update")){
				blog.setOper_type("03");
			}else if(methodName.startsWith("del") || methodName.startsWith("remove")){
				blog.setOper_type("02");
			}else if(methodName.startsWith("query") || methodName.startsWith("select") || methodName.startsWith("find") || methodName.startsWith("page")){
				blog.setOper_type("04");
			}else{
				blog.setOper_type("05");
			}
			
			original_data.append("\nresponse:\n");
			if(null != o){
				try {
					original_data.append(JsonUtil.toJson(o.getData()));
				} catch (Exception e) {
					e.printStackTrace();
				}
				blog.setResp_code(o.getStatus());
			}
			blog.setOriginal_data(original_data.toString());
			
			blog.setOriginal_link(request.getRequestURI());
			blog.setToDo(log.value()+"-->"+lm.value());
			
			logMapper.saveLog(blog);
		}
		
		return o;
    }
}
